package BehaviorPattern.Interpreter;

/**
 * @author: Themberfue
 * @date: 2025/8/14 11:09
 * @description:
 */
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;

// 1. 抽象表达式
interface Expression {
    int interpret(Map<String, Integer> variables);
}

// 2. 终结符表达式：数字或变量
class Number implements Expression {
    private int number;

    public Number(int number) {
        this.number = number;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return number;
    }
}

class Variable implements Expression {
    private String name;

    public Variable(String name) {
        this.name = name;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return variables.getOrDefault(name, 0);
    }
}

// 3. 非终结符表达式：加法
class Add implements Expression {
    private Expression leftExpression;
    private Expression rightExpression;

    public Add(Expression left, Expression right) {
        this.leftExpression = left;
        this.rightExpression = right;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return leftExpression.interpret(variables) + rightExpression.interpret(variables);
    }
}

// 3. 非终结符表达式：乘法
class Multiply implements Expression {
    private Expression leftExpression;
    private Expression rightExpression;

    public Multiply(Expression left, Expression right) {
        this.leftExpression = left;
        this.rightExpression = right;
    }

    @Override
    public int interpret(Map<String, Integer> variables) {
        return leftExpression.interpret(variables) * rightExpression.interpret(variables);
    }
}

// 4. 修复后的表达式解析器（处理运算符优先级）
class ExpressionParser {
    // 辅助方法：判断运算符优先级
    private static int precedence(String operator) {
        if (operator.equals("+") || operator.equals("-")) {
            return 1;
        }
        if (operator.equals("*") || operator.equals("/")) {
            return 2;
        }
        return 0;
    }

    // 将中缀表达式转换为后缀表达式（逆波兰表达式）
    private static String[] infixToPostfix(String[] tokens) {
        Stack<String> stack = new Stack<>();
        StringBuilder output = new StringBuilder();

        for (String token : tokens) {
            // 如果是数字或变量，直接加入输出
            if (Character.isLetterOrDigit(token.charAt(0))) {
                output.append(token).append(" ");
            }
            // 如果是运算符
            else {
                // 弹出栈中优先级更高或相等的运算符
                while (!stack.isEmpty() && precedence(stack.peek()) >= precedence(token)) {
                    output.append(stack.pop()).append(" ");
                }
                stack.push(token);
            }
        }

        // 弹出栈中剩余的运算符
        while (!stack.isEmpty()) {
            output.append(stack.pop()).append(" ");
        }

        return output.toString().split(" ");
    }

    public static Expression parse(String expression) {
        // 拆分表达式为令牌
        String[] tokens = expression.split(" ");
        // 转换为后缀表达式以处理优先级
        String[] postfixTokens = infixToPostfix(tokens);

        Stack<Expression> stack = new Stack<>();

        for (String token : postfixTokens) {
            if (token.isEmpty()) continue; // 跳过空字符串

            if (token.equals("+")) {
                Expression right = stack.pop();
                Expression left = stack.pop();
                stack.push(new Add(left, right));
            } else if (token.equals("*")) {
                Expression right = stack.pop();
                Expression left = stack.pop();
                stack.push(new Multiply(left, right));
            } else if (Character.isLetter(token.charAt(0))) {
                stack.push(new Variable(token));
            } else {
                stack.push(new Number(Integer.parseInt(token)));
            }
        }

        if (stack.isEmpty()) {
            throw new IllegalArgumentException("无效的表达式");
        }

        return stack.pop();
    }
}

// 5. 客户端代码
public class InterpreterExample {
    public static void main(String[] args) {
        // 定义表达式: a + 3 * b
        String expression = "a + 3 * b";
        System.out.println("表达式: " + expression);

        // 解析表达式，构建语法树
        Expression parsedExpression = ExpressionParser.parse(expression);

        // 设置变量值
        Map<String, Integer> variables = new HashMap<>();
        variables.put("a", 2);
        variables.put("b", 4);
        System.out.println("变量: a=2, b=4");

        // 解释执行表达式
        int result = parsedExpression.interpret(variables);
        System.out.println("结果: " + result); // 输出 (2 + (3 * 4)) = 14

        // 改变变量值，重新计算
        variables.put("a", 5);
        variables.put("b", 3);
        System.out.println("变量: a=5, b=3");
        result = parsedExpression.interpret(variables);
        System.out.println("结果: " + result); // 输出 (5 + (3 * 3)) = 14
    }
}

